﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;

namespace Susam
{
    //interface ISusamTwoColumnTable
    //{
    //    //int Add(susamDataSet ds, String str);
    //    IEnumerable<DataRow> GetTableAsList();
    //}

    abstract class SusamTableBase
    {
        protected IQueryable<System.Data.DataRow> table;

        protected virtual IEnumerable<int> GetIDList(String str)
        {
            var IdList =
                from row in table
                where ((String)row[1]).Equals(str, StringComparison.CurrentCultureIgnoreCase)
                select (int)row[0];

            return IdList;
        }

        protected virtual int GetID(String str)
        {
            var IdList = GetIDList(str);

            int id = -1;

            try
            {
                id = IdList.First();
            }
            catch (InvalidOperationException)
            {
                Debug.WriteLine("Entry doesn't exist in the database.");
                throw;
            }
            catch (Exception e)
            {
                Debug.WriteLine("{0}", e.ToString());
            }

            return id;
        }
    }

    class BookTable : SusamTableBase
    {
        public BookTable()
        {
            this.table = (IQueryable<System.Data.DataRow>)SusamDS.DataSet.tblBook.AsQueryable<System.Data.DataRow>();
        }

        protected override IEnumerable<int> GetIDList(String str)
        {
            var IdList =
                from row in SusamDS.DataSet.tblBook
                where row.BookURI.Equals(str, StringComparison.CurrentCultureIgnoreCase)
                select row.BookID;

            return IdList;
        }

        public int Add(Metadata meta)
        {
            int id;
            try
            {
                id = GetID(meta.ToString());
            }
            catch (InvalidOperationException)
            {
                Debug.WriteLine("Creating new Book entry...");
                var file = meta._file;

                // TODO: Hack
                if (meta.title == null) meta.title = " ";

                // TODO: Create a new "meta" table to store all the uniinteresting metadata
                var row = SusamDS.DataSet.tblBook.AddtblBookRow(meta.title, file.filePath, file.timestamp,
                    meta.isNewAddition, meta.identifierList.Any() ? meta.identifierList.First() : " ", file.fileName);

                SusamDS.DataSet.tblBook.AcceptChanges();
                id =  row.BookID;
            }
            SusamDS.DataSet.AcceptChanges();

            return id;
        }
    }

    abstract class SusamTwoColumnTableBase : SusamTableBase
    {
        protected delegate System.Data.DataRow AddToTable(String str);
        protected AddToTable addToTable;

        public int Add(String str)
        {
            int id;
            try
            {
                id = GetID(str);
            }
            catch (InvalidOperationException)
            {
                Debug.WriteLine("Creating new table entry...");
                var row = addToTable(str);
                SusamDS.DataSet.AcceptChanges();
                id =  (int)row[0];
            }

            return id;
        }
    }

    class PersonTable : SusamTwoColumnTableBase
    {
        public PersonTable()
        {
            this.table = (IQueryable<System.Data.DataRow>)SusamDS.DataSet.tblPerson.AsQueryable<System.Data.DataRow>();
            this.addToTable = SusamDS.DataSet.tblPerson.AddtblPersonRow;
        }
    }

    class FileTypeTable : SusamTwoColumnTableBase
    {
        public FileTypeTable()
        {
            this.table = (IQueryable<System.Data.DataRow>)SusamDS.DataSet.tblFileType.AsQueryable<System.Data.DataRow>();
            this.addToTable = SusamDS.DataSet.tblFileType.AddtblFileTypeRow;
        }
    }

    class PublisherTable : SusamTwoColumnTableBase
    {
        public PublisherTable()
        {
            this.table = (IQueryable<System.Data.DataRow>)SusamDS.DataSet.tblPublisher.AsQueryable<System.Data.DataRow>();
            this.addToTable = SusamDS.DataSet.tblPublisher.AddtblPublisherRow;
        }
    }

    class LanguageTable : SusamTwoColumnTableBase
    {
        public LanguageTable()
        {
            this.table = (IQueryable<System.Data.DataRow>)SusamDS.DataSet.tblLanguage.AsQueryable<System.Data.DataRow>();
            this.addToTable = SusamDS.DataSet.tblLanguage.AddtblLanguageRow;
        }
    }

}
